package com.hsxxherp.simplify.framework.utils;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;


/**
 * json 工具类
 * <p>
 *     基于jackson 实现
 * </p>
 *
 * @author Mark·虎克 (2486970363@qq.com)
 */
public class JsonUtil {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 配置 ObjectMapper
        // 序列化时，允许没有属性的空对象转换为 JSON
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 反序列化时，忽略 JSON 中存在但 Java 对象中不存在的属性
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 配置 Date 类型的序列化和反序列化格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        OBJECT_MAPPER.setDateFormat(dateFormat);
        OBJECT_MAPPER.registerModule(new SimpleModule().addSerializer(Date.class, new DateSerializer(false, dateFormat)));

        // 配置 Java 8 日期时间类型的序列化和反序列化格式
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // LocalDate 序列化和反序列化格式
        DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(localDateFormatter));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(localDateFormatter));

        // LocalDateTime 序列化和反序列化格式
        DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));

        // 禁用默认的时间戳序列化
        OBJECT_MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        OBJECT_MAPPER.registerModule(javaTimeModule);

    }

    /**
     * 将 Java 对象序列化为 JSON 字符串
     * @param object 要序列化的 Java 对象
     * @return 序列化后的 JSON 字符串
     */
    public static String toJson(Object object) {
        try {
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (Exception e) {
            // 处理序列化异常
            throw new RuntimeException("序列化失败！", e);
        }
    }

    /**
     * 将 JSON 字符串反序列化为指定类型的 Java 对象
     * @param json 要反序列化的 JSON 字符串
     * @param clazz 目标 Java 对象的类型
     * @param <T> 泛型类型
     * @return 反序列化后的 Java 对象
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (Exception e) {
            // 处理序列化异常
            throw new RuntimeException("反序列化失败！", e);
        }
    }
}